import React, { useState, useRef, useContext,createContext } from 'react';
import { Sider, Header, Footer, Splitter, ToolBar } from '.';
import type { CommonContainerProps } from '../common/types';
import { Column, Flex, Row } from '../FlexBox';


// 定义布局组件类型
const LAYOUT_COMPONENTS: any[] = [Sider, Header, Footer, ToolBar, Splitter];


/**
 * 布局组件，包含 Sider、Header、Footer、Content
 * 其中Sider，Content 有着和Layout相似的功能，会把Footer和Header 放在自己的所有子元素的最上面或者最下面
 * 其他属性默认被Content包裹
 * 后期可能会通过拖拽,或者配置来控制这些面板,最终形态会完全支持类似vscode这样复杂的多面板程序的功能
 */
function DraggableColumn({ children }: { children: React.ReactNode[] }) {
    // children: [Header, Content, Footer]（已按顺序）
    const count = children.length;
    // 初始高度分配为均分
    const [sizes, setSizes] = useState(Array(count).fill(1 / count));
    const startPos = useRef<number | null>(null);
    const startSizes = useRef<number[]>([]);
    const draggingIndex = useRef<number | null>(null);

    function handleDragStart(idx: number, e: React.MouseEvent) {
        draggingIndex.current = idx;
        startPos.current = e.clientY;
        startSizes.current = [...sizes];
        document.addEventListener('mousemove', handleDrag as any);
        document.addEventListener('mouseup', handleDragEnd as any);
    }
    function handleDrag(e: MouseEvent) {
        if (draggingIndex.current == null || startPos.current == null) return;
        const delta = e.clientY - startPos.current;
        const totalHeight = (document.body as HTMLElement).clientHeight; // 可根据实际容器高度调整
        const idx = draggingIndex.current;
        // 只影响idx和idx+1
        const prev = startSizes.current[idx] * totalHeight + delta;
        const next = startSizes.current[idx + 1] * totalHeight - delta;
        const min = 40; // 最小高度
        if (prev < min || next < min) return;
        const newTotal = prev + next;
        const newSizes = [...startSizes.current];
        newSizes[idx] = prev / totalHeight;
        newSizes[idx + 1] = next / totalHeight;
        setSizes(newSizes);
    }
    function handleDragEnd() {
        draggingIndex.current = null;
        startPos.current = null;
        document.removeEventListener('mousemove', handleDrag as any);
        document.removeEventListener('mouseup', handleDragEnd as any);
    }
    // 渲染区块和Splitter
    const nodes: React.ReactNode[] = [];
    for (let i = 0; i < count; i++) {
        nodes.push(
            <div key={i} style={{ flex: sizes[i], minHeight: 40, overflow: 'auto' }}>
                {children[i]}
            </div>
        );
        if (i < count - 1) {
            nodes.push(
                <div
                    key={`splitter-${i}`}
                    style={{ height: 6, background: '#ccc', cursor: 'row-resize', zIndex: 1 }}
                    onMouseDown={e => handleDragStart(i, e)}
                />
            );
        }
    }
    return <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>{nodes}</div>;
}

function ResizablePair({ left, right, direction = 'vertical', splitter }: { left: React.ReactNode, right: React.ReactNode, direction?: 'vertical' | 'horizontal', splitter: React.ReactNode }) {
    // 只支持纵向（上下）
    const [leftSize, setLeftSize] = useState(0.5);
    const startPos = useRef<number | null>(null);
    const startSize = useRef<number>(0.5);
    function handleDragStart(e: React.MouseEvent) {
        startPos.current = direction === 'vertical' ? e.clientY : e.clientX;
        startSize.current = leftSize;
        document.addEventListener('mousemove', handleDrag as any);
        document.addEventListener('mouseup', handleDragEnd as any);
    }
    function handleDrag(e: MouseEvent) {
        if (startPos.current == null) return;
        const delta = (direction === 'vertical' ? e.clientY : e.clientX) - startPos.current;
        const total = (direction === 'vertical' ? window.innerHeight : window.innerWidth);
        let newLeft = startSize.current + delta / total;
        newLeft = Math.max(0.1, Math.min(0.9, newLeft));
        setLeftSize(newLeft);
    }
    function handleDragEnd() {
        startPos.current = null;
        document.removeEventListener('mousemove', handleDrag as any);
        document.removeEventListener('mouseup', handleDragEnd as any);
    }
    return (
        <div style={{ display: 'flex', flexDirection: direction === 'vertical' ? 'column' : 'row', height: '100%', width: '100%' }}>
            <div style={{ flex: leftSize, minHeight: 40, minWidth: 40, overflow: 'auto' }}>{left}</div>
            <div
                style={{ height: direction === 'vertical' ? 6 : '100%', width: direction === 'vertical' ? '100%' : 6, background: '#ccc', cursor: direction === 'vertical' ? 'row-resize' : 'col-resize', zIndex: 1 }}
                onMouseDown={handleDragStart}
            >{splitter}</div>
            <div style={{ flex: 1 - leftSize, minHeight: 40, minWidth: 40, overflow: 'auto' }}>{right}</div>
        </div>
    );
}

function extractLayout(children: React.ReactNode): React.ReactNode {
    const childrenArray = React.Children.toArray(children);
    const layoutTypes = [Sider, Header, Footer, Content];
    if (!childrenArray.some(child => React.isValidElement(child) && layoutTypes.includes((child as React.ReactElement<any>).type as any))) {
        return children;
    }

    type Group = { type: 'sider', nodes: React.ReactElement[] } | { type: 'content', nodes: React.ReactElement[] };
    const groups: Group[] = [];
    let currentType: 'sider' | 'content' | null = null;
    let currentNodes: React.ReactElement[] = [];

    function pushGroup() {
        if (currentNodes.length === 0) return;
        if (currentType) {
            groups.push({ type: currentType, nodes: currentNodes });
        }
        currentNodes = [];
    }

    childrenArray.forEach(child => {
        if (!React.isValidElement(child)) return;
        const el = child as React.ReactElement<any>;
        if (el.type === Sider) {
            if (currentType !== 'sider') {
                pushGroup();
                currentType = 'sider';
            }
            currentNodes.push(React.cloneElement(el, el.props, extractLayout(el.props.children)));
        } else if (el.type === Header || el.type === Footer || el.type === Content) {
            if (currentType !== 'content') {
                pushGroup();
                currentType = 'content';
            }
            currentNodes.push(React.cloneElement(el, el.props, extractLayout(el.props.children)));
        }
        // 其它布局组件忽略
    });
    pushGroup();

    // 渲染分组
    const nodes = groups.map((group, idx) => {
        if (group.type === 'sider') {
            return group.nodes.map((n, i) => React.cloneElement(n, { key: `${idx}-sider-${i}` }));
        } else {
            // 内容区内部Header/Content/Footer纵向排列
            let header: React.ReactElement | null = null;
            let content: React.ReactElement | null = null;
            let footer: React.ReactElement | null = null;
            group.nodes.forEach(item => {
                if (item.type === Header) header = item;
                else if (item.type === Content) content = item;
                else if (item.type === Footer) footer = item;
            });
            let contentGroup: React.ReactNode[] = [];
            if (header) contentGroup.push(header);
            if (content) {
                contentGroup.push(content);
            } else if (header || footer) {
                contentGroup.push(<Content key="__auto__empty" />);
            }
            if (footer) contentGroup.push(footer);
            return (
                <Column key={idx} style={{ height: '100%' }}>{contentGroup}</Column>
            );
        }
    });
    // 横向排列
    return <Row style={{ width: '100%', height: '100%' }}>{nodes}</Row>;
}
const ContentContext = createContext(false);

export function Content({ children, as: asElement = 'div', style, ...rest }: CommonContainerProps) {
    const inParentContent = useContext(ContentContext);

    const Component = asElement;
    const mergedStyle = inParentContent
        ? {
            flex: 1,
            minWidth: 0,
            minHeight: 0,
            ...style
        }
        : {
            width: '100%',
            height: '100%',
            ...style
        };
    return (
        <ContentContext.Provider value={true}>
            <Component style={mergedStyle} {...rest}>
                {extractLayout(children)}
            </Component>
        </ContentContext.Provider>
    );
}